Skip to content

Node: Add new Advanced Topics lesson - #31398

Open
ZackHoang wants to merge 20 commits into
TheOdinProject:mainfrom
ZackHoang:node/advanced-topics
Open

ZackHoang wants to merge 20 commits into
TheOdinProject:mainfrom
ZackHoang:node/advanced-topics

Conversation

@ZackHoang

Copy link
Copy Markdown
Contributor

Because

This new lesson is part of the Node Revamp project to be added to introduce learners to more advanced concepts in web development that learners will do more exploring on their own.

This PR

  • Explain what Conent Security Policy is and how it helps protect users from XSS and clickjacking
  • Explain how logging can be helpful in pinpointing exact errors where an application might fail and what not include in log files
  • Explain what Cross Site Request Forgery is and how CSFR tokens could be used to mitigate
  • Explain what Internationalisation is and when a library like i18njs could help
  • Explain what Cross-Origin Resource Sharing is and when a pre-flight request might be triggered
  • Explain what rate-limiting is, as well as where it could be employed and how it is commonly done

Issue

Closes #29531

Additional Information

Pull Request Requirements

  • I have thoroughly read and understand The Odin Project curriculum contributing guide
  • The title of this PR follows the location of change: brief description of change format, e.g. Intro to HTML and CSS lesson: Fix link text
  • The Because section summarizes the reason for this PR
  • The This PR section has a bullet point list describing the changes in this PR
  • If this PR addresses an open issue, it is linked in the Issue section
  • If any lesson files are included in this PR, they have been previewed with the Markdown preview tool to ensure it is formatted correctly
  • If any lesson files are included in this PR, they follow the Layout Style Guide

@github-actions github-actions Bot added the Content: NodeJS Involves the NodeJS course label Sep 18, 2026
@mao-sz mao-sz added the Project Node Revamp Issues/PRs related to the Node Revamp project label Sep 18, 2026
@mao-sz
mao-sz requested review from 01zulfi and mao-sz September 18, 2026 10:20

@Maddily Maddily left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left small suggestions throughout: typo fixes, grammar, a couple of technical corrections, and some redundant phrasing tightened for clarity. Nothing structural, just polish. Great lesson overall!

Comment thread nodeJS/final_project/advanced_topics.md Resolved
Comment thread nodeJS/final_project/advanced_topics.md Resolved
Comment thread nodeJS/final_project/advanced_topics.md Resolved
Comment thread nodeJS/final_project/advanced_topics.md Resolved
Comment thread nodeJS/final_project/advanced_topics.md Resolved
Comment thread nodeJS/final_project/advanced_topics.md Resolved
Comment thread nodeJS/final_project/advanced_topics.md Resolved
Comment thread nodeJS/final_project/advanced_topics.md Resolved
Comment thread nodeJS/final_project/advanced_topics.md Resolved
Comment thread nodeJS/final_project/advanced_topics.md Resolved
@ZackHoang

Copy link
Copy Markdown
Contributor Author

@Maddily Thanks a lot for having taken a much closer look and scrutinize this lesson! Since commit history is getting pretty long, I'll just squash them first locally and push to make the history look more succinct :)

@mao-sz mao-sz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking great! Got some initial comments, some small fixes and some larger conceptual ideas. As always, feel free to push back on anything if you feel justified.

Comment thread nodeJS/final_project/advanced_topics.md Resolved
Comment thread nodeJS/final_project/advanced_topics.md Resolved
Comment thread nodeJS/final_project/advanced_topics.md Resolved
Comment thread nodeJS/final_project/advanced_topics.md Resolved
Comment thread nodeJS/final_project/advanced_topics.md Resolved
Comment thread nodeJS/final_project/advanced_topics.md Resolved
Comment thread nodeJS/final_project/advanced_topics.md Resolved
Comment thread nodeJS/final_project/advanced_topics.md Resolved
Comment thread nodeJS/final_project/advanced_topics.md Resolved
Comment thread nodeJS/final_project/advanced_topics.md Resolved
ZackHoang and others added 5 commits September 19, 2026 15:57
Co-authored-by: mao-sz <122839503+mao-sz@users.noreply.github.com>
It was being too much "if you do this everything will be okay"

Co-authored-by: mao-sz <122839503+mao-sz@users.noreply.github.com>
Co-authored-by: mao-sz <122839503+mao-sz@users.noreply.github.com>
Co-authored-by: mao-sz <122839503+mao-sz@users.noreply.github.com>
@ZackHoang
ZackHoang requested a review from mao-sz September 20, 2026 00:21
@mao-sz mao-sz moved this to In Progress in Node Revamp Sep 25, 2026
Comment thread nodeJS/final_project/advanced_topics.md Resolved
Co-authored-by: Goran Jović <goran1010jovic@gmail.com>
@mao-sz

mao-sz commented Sep 25, 2026

Copy link
Copy Markdown
Contributor

Curious as to why the linter passes here when the branch hasn't been synced with main yet (the markdownlint workflow runs on pull_request i.e. incoming context, not pull_request_target) 🤔

Comment thread nodeJS/final_project/advanced_topics.md Resolved
Co-authored-by: mao-sz <122839503+mao-sz@users.noreply.github.com>
@ZackHoang
ZackHoang requested a review from mao-sz September 25, 2026 21:05
@goran1010

goran1010 commented Sep 25, 2026 •

Copy link
Copy Markdown
Member

Curious as to why the linter passes here when the branch hasn't been synced with main yet (the markdownlint workflow runs on pull_request i.e. incoming context, not pull_request_target) 🤔

@mao-sz https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows#how-the-merge-branch-affects-your-workflow - this?
Seems the way gh checks out what branch to run ci workflow on is some sort of special merge branch - current main + pr branch.

Comment thread nodeJS/final_project/advanced_topics.md Resolved
Comment thread nodeJS/final_project/advanced_topics.md Resolved
ZackHoang and others added 2 commits October 1, 2026 10:03
Co-authored-by: Goran Jović <goran1010jovic@gmail.com>
Co-authored-by: Goran Jović <goran1010jovic@gmail.com>
@ZackHoang
ZackHoang requested a review from goran1010 October 1, 2026 17:04

@mao-sz mao-sz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Content on CORS is now going to come in the JSON Web Tokens lesson, so no need to include it in this anymore.

@ZackHoang
ZackHoang requested a review from mao-sz October 4, 2026 03:34
Comment thread nodeJS/final_project/advanced_topics.md Resolved
Co-authored-by: Goran Jović <goran1010jovic@gmail.com>
@ZackHoang
ZackHoang requested a review from goran1010 October 4, 2026 18:58
Comment thread nodeJS/final_project/advanced_topics.md Resolved
Comment on lines +28 to +48
### Cross-Site Request Forgery

Another very common exploit in the World Wide Web. Imagine you encountered a strange but very innocent looking website called `cutekittens.com`...until you inspect its HTML that looks like this.

```html
<form action="https://my-bank.example.org/transfer" method="POST">
<input type="hidden" name="recipient" value="attacker" />
<input type="hidden" name="amount" value="1000" />
</form>
```

Then, within that site, a small but very dangerous snippet of JavaScript is embedded and will be loaded if anyone clicked on it...

```javascript
const form = document.querySelector("form");
form.submit();
```

Assuming you are still logged in and your banking app's cookies still persist, disaster has already been struck! "Wait, I just want to see kittens! Why is my money gone?!" Yikes, you don't want that, right? [Cross-Site Request Forgery (CSRF) attacks](https://developer.mozilla.org/en-US/docs/Web/Security/Attacks/CSRF) are just that: tricking a user into performing a state-changing request to a certain target site from a malicious site. In this case, a form was automatically submit the moment you landed on `cutekittnes.com` and a banking transaction was silently performed.

So what could you do about it? One of the most common methods is to use a CSRF token. Every time you prompt your user to perform some state-changing request in your application, check for a hidden, unpredictable key (this could be embedded inside a `<form>` or an HTTP request header). Then, in your app, carry out the request if and only if the token is valid.

@mao-sz mao-sz Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I think makes this section incomplete is that it's not quite clear exactly where the learner stands in relation to all this.
e.g. from this section, I can absolutely see a learner going "how would I use a CSRF token here? I don't have anything to do with cutekittens.com nor my-bank.example.org!"
The example used here makes sense but it's the bank site's responsibility to implement anti-CSRF measures, not the user's responsibility.

This section needs to clearly frame things so that it's relevant to the learner and them building sites/servers. The problem is specifically that if they're building something, not using anti-CSRF techniques like CSRF tokens is what can allow a malicious site to make a malicious request. By using something like CSRF tokens, a malicious site can certainly try a CSRF attack on your site but since they won't have the correct token, the request will not succeed.

So this example can be kept but instead of saying "So what could you do about it?" (which makes it sound like the user is the one to protect the banking site), frame it as what the banking site could do to protect against CSRF.
Then expand by framing things for when the learner is making their own sites, and how they can use stuff like CSRF tokens to protect users of their sites from CSRF.

Comment on lines +28 to +48
### Cross-Site Request Forgery

Another very common exploit in the World Wide Web. Imagine you encountered a strange but very innocent looking website called `cutekittens.com`...until you inspect its HTML that looks like this.

```html
<form action="https://my-bank.example.org/transfer" method="POST">
<input type="hidden" name="recipient" value="attacker" />
<input type="hidden" name="amount" value="1000" />
</form>
```

Then, within that site, a small but very dangerous snippet of JavaScript is embedded and will be loaded if anyone clicked on it...

```javascript
const form = document.querySelector("form");
form.submit();
```

Assuming you are still logged in and your banking app's cookies still persist, disaster has already been struck! "Wait, I just want to see kittens! Why is my money gone?!" Yikes, you don't want that, right? [Cross-Site Request Forgery (CSRF) attacks](https://developer.mozilla.org/en-US/docs/Web/Security/Attacks/CSRF) are just that: tricking a user into performing a state-changing request to a certain target site from a malicious site. In this case, a form was automatically submit the moment you landed on `cutekittnes.com` and a banking transaction was silently performed.

So what could you do about it? One of the most common methods is to use a CSRF token. Every time you prompt your user to perform some state-changing request in your application, check for a hidden, unpredictable key (this could be embedded inside a `<form>` or an HTTP request header). Then, in your app, carry out the request if and only if the token is valid.

@mao-sz mao-sz Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A separate thing I want to also point out about this section is that it probably won't be clear to learners exactly where the bank site URL comes from. The point is that whoever made the malicious site knows the URL (and params) that could get them what they want, and that's why they crafted the request URL in that way (see https://stackoverflow.com/a/33829607 for more context). It's not just any ol' URL/request to some random site.

Comment thread nodeJS/final_project/advanced_topics.md Resolved
Comment thread nodeJS/final_project/advanced_topics.md Outdated

Eventually, you might want to adapt your app to a wider range of audiences around the world. [Internationalization (I18n)](https://learn.microsoft.com/en-us/globalization/methodology/software-internationalization) is a process of adapting your applications to different populations/languages. This could involve taking a look at a client's [Accept-Language header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Accept-Language) and serve the content in the language that they want to see.

MDN documentations also accommodate a wide range of languages! For example, <https://developer.mozilla.org/fr/> will display all your pages in MDN in French! C'est pratique, non?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. "documentation" is an uncountable noun (i.e. no plural)
  2. Rephrasing for better flow from the previous line. Starting straight with "MDN also accommodates..." reads to me a little like it's out of nowhere.
Suggested change
MDN documentations also accommodate a wide range of languages! For example, <https://developer.mozilla.org/fr/> will display all your pages in MDN in French! C'est pratique, non?
For example, MDN can accommodate a wide range of languages! For example, <https://developer.mozilla.org/fr/> will display all your pages in MDN in French! C'est pratique, non?

Comment thread nodeJS/final_project/advanced_topics.md Outdated

Eventually, you might want to adapt your app to a wider range of audiences around the world. [Internationalization (I18n)](https://learn.microsoft.com/en-us/globalization/methodology/software-internationalization) is a process of adapting your applications to different populations/languages. This could involve taking a look at a client's [Accept-Language header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Accept-Language) and serve the content in the language that they want to see.

MDN documentations also accommodate a wide range of languages! For example, <https://developer.mozilla.org/fr/> will display all your pages in MDN in French! C'est pratique, non?

@mao-sz mao-sz Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about something like this:

Suggested change
MDN documentations also accommodate a wide range of languages! For example, <https://developer.mozilla.org/fr/> will display all your pages in MDN in French! C'est pratique, non?
For example, MDN can accommodate a wide range of languages! [MDN maintains a lot of translated content for various languages](https://github.com/mdn/translated-content), including [French](https://developer.mozilla.org/fr/ "MDN docs in French") and [German](https://developer.mozilla.org/de/ "MDN docs in German").

I think it's a good idea to make it clear that internationalisation is something that has to be manually implemented and not some automatic translation that can be done for any site by just adding headers. While the current text kinda hints at that, actually linking MDN's translated-content repo should make it much clearer that it's a pretty damn big job that has to be manually worked on (they only provide content for certain languages too, not just automatic translation for anything).

Also providing more than one language example feels nicer IMO (but that's just a nit; also using our style guide's aria-label/title links syntax for visually nicer links while still remaining sufficiently accessible.

Comment thread nodeJS/final_project/advanced_topics.md Resolved
Comment thread nodeJS/final_project/advanced_topics.md Resolved
Comment thread nodeJS/final_project/advanced_topics.md Resolved
ZackHoang and others added 6 commits October 26, 2026 10:54
Co-authored-by: mao-sz <122839503+mao-sz@users.noreply.github.com>
Co-authored-by: mao-sz <122839503+mao-sz@users.noreply.github.com>
Co-authored-by: mao-sz <122839503+mao-sz@users.noreply.github.com>
Co-authored-by: mao-sz <122839503+mao-sz@users.noreply.github.com>
Co-authored-by: mao-sz <122839503+mao-sz@users.noreply.github.com>
Co-authored-by: mao-sz <122839503+mao-sz@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Content: NodeJS Involves the NodeJS course Project Node Revamp Issues/PRs related to the Node Revamp project

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

New Lesson: Advanced Topics (Node)

4 participants